import { Model } from 'mongoose';
import { Injectable, Inject, LoggerService } from '@nestjs/common';
import { Work, WorkDocument } from './schemas/work.schema';
import { InjectModel } from '@nestjs/mongoose';
import { ValidationException } from '@/common/exceptions/custom-exception';
import { IndexCondition } from './work.controller';
import configuration from '@/config/configuration';

const defaultIndexCondition: Required<IndexCondition> = {
  pageIndex: 0,
  pageSize: 10,
  select: '',
  populate: null,
  customSort: { createdAt: -1 },
  find: {},
};

@Injectable()
export class WorkService {
  constructor(
    @InjectModel(Work.name) private workModel: Model<WorkDocument>,
    @Inject('CustomLogger') private readonly logger: LoggerService,
  ) {}

  async createChannel(channelInfo: {
    channelName: string;
    workId: string;
  }): Promise<Work> {
    await this.workModel.findOneAndUpdate(
      { uuid: channelInfo.workId },
      {
        $push: { channels: { channelName: channelInfo.channelName } },
      },
    );
    return this.workModel.findOne({ uuid: channelInfo.workId }).lean();
  }

  async getWorkChannel({ workId }) {
    const channles = await this.workModel
      .findOne({ uuid: workId })
      .select('channels')
      .lean();
    return { count: channles.channels.length, list: channles.channels };
  }

  async updateChannelName({
    channelId,
    channelName,
  }: {
    channelId: string;
    channelName: string;
  }) {
    try {
      const res = this.workModel.findOneAndUpdate(
        { 'channels._id': channelId },
        {
          $set: { 'channels.$.channelName': channelName },
        },
        { new: true },
      );
      return res;
    } catch (error) {
      this.logger.error('更新频道名称失败', error);
      throw new ValidationException('channelValidateFail');
    }
  }

  async deleteChannel({ channelId }) {
    try {
      const res = await this.workModel.findOneAndUpdate(
        { 'channels._id': channelId },
        {
          $pull: { channels: { _id: channelId } },
        },
        { new: true },
      );

      return res;
    } catch (err) {
      // 可以记录日志或自定义错误类型
      this.logger.error('删除频道失败', err);
      throw new ValidationException('channelValidateFail');
    }
  }

  async createWork(workInfo): Promise<Work> {
    try {
      const createWork = new this.workModel(workInfo);
      return await createWork.save();
    } catch (error) {
      this.logger.error('创建work失败', error);
      throw new ValidationException('workValidateFail');
    }
  }

  async getList(condition: IndexCondition) {
    const fcondition = { ...defaultIndexCondition, ...condition };
    const { pageIndex, pageSize, select, populate, customSort, find } =
      fcondition;
    const skip = pageIndex * pageSize;
    const res = await this.workModel
      .find(find)
      .select(select)
      .populate(populate)
      .skip(skip)
      .limit(pageSize)
      .sort(customSort)
      .lean();
    const count = await this.workModel.find(find).countDocuments();
    return { list: res, count, pageIndex, pageSize };
  }

  async updateOneWork({ workId, updateContation }) {
    return this.workModel
      .findOneAndUpdate({ uuid: workId }, { ...updateContation }, { new: true })
      .lean();
  }

  async deleteOneWork({ workId }) {
    return this.workModel
      .findOneAndDelete({ uuid: workId }, { new: true })
      .select(['_id', 'id', 'title'])
      .lean();
  }

  async publishWork({ workId }) {
    const res = await this.workModel
      .findOneAndUpdate({ uuid: workId }, { status: 2 }, { new: true })
      .lean();
    return { url: `${configuration().h5BaseUrl}/${res.uuid}` };
  }

  async publishTemplate({ workId }) {
    return this.workModel
      .findOneAndUpdate({ uuid: workId }, { isTemplate: true }, { new: true })
      .lean();
  }
}
